package com.youlai.common.base;

import com.youlai.common.result.PageResult;
import com.youlai.common.result.Result;
import com.youlai.utils.DateUtils;
import com.youlai.system.util.SecurityUtils;
import com.youlai.core.security.model.SysUserDetails;
import com.youlai.system.service.SysDictService;
import com.youlai.utils.GenericsUtils;
import jakarta.annotation.Resource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

public abstract class BaseService<T extends BaseEntity>  {

    protected Class entityClass;

    public BaseService() {
        this.entityClass = GenericsUtils.getSuperClassGenricType(this
                .getClass());
    }

    @PersistenceContext
    private EntityManager em;

    public EntityManager getEntityManager() {
        return em;
    }

    @Resource
    SysDictService sysDictService;

    /**
     * 分页查询列表
     *
     * @param queryParams
     * @return
     */
    public PageResult<T> getPageByHql(BasePageQuery queryParams, String hql) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();

        DateUtils.toDatabaseFormat(queryParams, "startUpdateTime", "endUpdateTime");
        if (StringUtils.isNotEmpty(queryParams.getStartUpdateTime())) {
            hql += " and DATE_FORMAT(t.updateTime, '%Y-%m-%d %H:%i:%s') >=  '"+ queryParams.getStartUpdateTime()  +"'  ";
        }
        if (StringUtils.isNotEmpty(queryParams.getEndUpdateTime())) {
            hql += " and DATE_FORMAT(t.updateTime, '%Y-%m-%d %H:%i:%s') <=  '"+ queryParams.getEndUpdateTime()  +"'  ";
        }

        // 查询数据
        PageBean pageBean = new PageBean();
        pageBean.setPage(pageNum);
        pageBean.setRows(pageSize);
        String countHql = getCountHql(hql);
        Query countQuery = em.createQuery(countHql);
        pageBean.setTotal(countQuery.getSingleResult().toString());

        hql += " order by t.updateTime desc ";
        Query query = em.createQuery(hql);
        query.setFirstResult(pageBean.getStartIndex());
        query.setMaxResults(pageBean.getRows());
        List<T> list = query.getResultList();
        PageResult page = PageResult.success(list, pageBean.getTotal());
        return page;
    }

    public String getCountHql(String hql) {
        //hql = "from Book where bookName like :bookName"
        //hql = " select * from new Book where(bid,bookName) where bookName like :bookName"
        int index = hql.toUpperCase().indexOf("FROM");
        return "select count(1) " +hql.substring(index);
    }
    protected void beforeSave(T entity, Boolean isCreate) {
    }

    public Result<T> save(T entity, Boolean isCreate){
        String method = "";
        SysUserDetails user = SecurityUtils.getUser();
        if (isCreate) {
            method = "Create";
            entity.setCreateBy(user.getUserId());
            entity.setCreateName(user.getUsername());
            entity.setUpdateBy(user.getUserId());
            entity.setUpdateName(user.getUsername());
        } else {
            entity.setUpdateBy(user.getUserId());
            entity.setUpdateName(user.getUsername());
        }

        this.beforeSave(entity, isCreate);

        em.merge(entity);
        return this.afterSave(entity,method);
    }

    protected Result<T> afterSave(T entity,String method) {
        return  Result.judge(true);
    }

    public T findById(String hql){
        Query query = em.createQuery(hql);
        T entity = (T)query.getSingleResult();
        return entity;
    }

    public List<T> findListBy(T entity, String hql){
        Query query = em.createQuery(hql);
        List<T> list = query.getResultList();
        return list;
    }

    public Boolean deleteAllById(String idStrs){
        SysUserDetails user = SecurityUtils.getUser();
        // 逻辑删除
        List<Long> ids = Arrays.asList(idStrs.split(",")).stream()
                .map(idStr -> Long.parseLong(idStr)).collect(Collectors.toList());
        for(Long id:ids) {
            T entity  = (T)em.find(entityClass,id);
            if(entity !=null) {
                entity.setDeleted(1);
                entity.setUpdateBy(user.getUserId());
                entity.setUpdateName(user.getUsername());
                em.merge(entity);
            }
        }
        return true;
    }

}


